package org.tinygroup.bizframe.aop.xmlfileparser;

import java.lang.reflect.Method;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import org.tinygroup.bizframe.aop.config.base.Extension;
import org.tinygroup.bizframe.aop.config.base.ExtensionAction;
import org.tinygroup.bizframe.aop.config.base.ExtensionActions;
import org.tinygroup.bizframe.aop.config.base.Extensions;
import org.tinygroup.bizframe.aop.config.base.MethodConfig;
import org.tinygroup.bizframe.aop.config.base.ParameterType;
import org.tinygroup.bizframe.aop.config.base.SearchTypeTableItem;
import org.tinygroup.bizframe.aop.interceptor.MethodDescription;

public class ExtensionActionXmlManager {
    public static final String XSTEAM_PACKAGE_NAME = "extensions";

    private Map<String,SearchTypeTableItem> typeMapping = new HashMap <String,SearchTypeTableItem>();
    
    private Map<MethodDescription, ExtensionActions> methodActionMap = new HashMap<MethodDescription, ExtensionActions>();

    public void addExtensions(Extensions extensions) {
        List<Extension> extensionList = extensions.getExtensionList();
        for (Extension extension : extensionList) {
            List<MethodConfig> methodConfigs = extension.getMethodConfigs();
            for (MethodConfig methodConfig : methodConfigs) {
                MethodDescription methodDescription = assembleMethodDescription(extension, methodConfig);
                methodActionMap.put(methodDescription, methodConfig.getExtensionActions());
            }
        }
        List<SearchTypeTableItem> searchTypeTableItems = extensions.getSearchTypeTableItems();
        for(SearchTypeTableItem item : searchTypeTableItems){
        	typeMapping.put(item.getSearchType(), item);
        }
    }

    public void removeExtensions(Extensions extensions) {
        List<Extension> extensionList = extensions.getExtensionList();
        for (Extension extension : extensionList) {
            List<MethodConfig> methodConfigs = extension.getMethodConfigs();
            for (MethodConfig methodConfig : methodConfigs) {
                MethodDescription methodDescription = assembleMethodDescription(extension, methodConfig);
                methodActionMap.remove(methodDescription);
            }
        }
        List<SearchTypeTableItem> searchTypeTableItems = extensions.getSearchTypeTableItems();
        for(SearchTypeTableItem item : searchTypeTableItems){
        	typeMapping.remove(item.getSearchType());
        }
    }

    public List<ExtensionAction> getActionsByMethod(Method method) {
        MethodDescription description = MethodDescription.createMethodDescription(method);
        ExtensionActions extensionActions = methodActionMap.get(description);
        if (extensionActions != null) {
            return extensionActions.getActions();
        }
        return null;
    }
    
    public SearchTypeTableItem getSearchTypeTableItemByType(String searchType){
    	return typeMapping.get(searchType);
    }

    private MethodDescription assembleMethodDescription(Extension extension, MethodConfig methodConfig) {
        MethodDescription description = new MethodDescription();
        description.setClassName(extension.getClassName());
        description.setMethodName(methodConfig.getMethodName());
        List<ParameterType> paramTypes = methodConfig.getParamTypes();
        StringBuilder typeBuilder = new StringBuilder();
        for (int i = 0; i < paramTypes.size(); i++) {
            typeBuilder.append(paramTypes.get(i).getType());
//            if (i < paramTypes.size() - 1) {
            typeBuilder.append(";");
//            }
        }
        description.setParameterTypes(typeBuilder.toString());
        return description;
    }
}